<template>
  <NavBar
    :leftArrow="true"
    :title="navTitle"
    @onClickLeft="goBack" />
  <div class="page">
    <div class="info-wrap">
      <div
        :class="{
          'info-box': true,
          'info-box-error': infoState === 0,
          'info-box-success': infoState === 1,
        }">
        <div class="title">{{ title }}</div>
        <div>{{ content }}</div>
        <!-- <div
          v-if="read.type"
          class="text">
          类型：{{ read.type }}
        </div> -->
        <div
          v-if="read.payload"
          class="text">
          内容：{{ read.payload }}
        </div>
      </div>
    </div>

    <scroll-div
      scroll-y
      class="key-list">
      <div
        v-for="item in keyList"
        :key="item.index"
        class="key-item">
        <div class="top-block">
          <div class="idx">{{ item.idx }}：</div>
          <div class="content">{{ item.text }}</div>
        </div>
        <div class="bottom-block">
          <button
            class="btn"
            :type="btnTypes[item.writeState]"
            :data-item="item"
            @click="onWriteNdefInfo">
            写入
          </button>
          <button
            class="btn"
            :type="btnTypes[item.verificationState]"
            :data-item="item"
            @click="onValidate">
            验证
          </button>
        </div>
      </div>
      <div class="end-item">END</div>
    </scroll-div>
  </div>
</template>

<script>
import NavBar from "../../components/NavBar/NavBar.vue";

import {
  byteToString,
  isEmpty,
  formatNullCharacter,
  throttle,
  generateUUID,
} from "../../utils/nfc.js";
export default {
  name: "NFCWriteList",
  components: {
    NavBar,
  },
  data() {
    return {
      navTitle: "写入",
      NFCAdapter: null,
      btnTypes: {
        0: "default",
        1: "primary",
        2: "warn",
      },
      currentWriteNdef: "",
      key: "",
      keyList: [],
      title: "",
      content: "",
      read: {},
      writeItem: {},
      validateItem: {},
      infoState: 1,
    };
  },
  onLoad(options) {
    const key = options.key || "record_5241db3580af4717b5e8c8ed0f6ea95f";
    const keyList = wx.getStorageSync(key);

    this.key = key;
    this.keyList = keyList;
  },
  onShow() {
    this.NFCAdapter = wx.getNFCAdapter();
    this.NFClistener();
  },
  onHide() {
    this.closeNFC();
  },
  onUnload() {
    this.closeNFC();
  },
  methods: {
    // 返回上一页
    goBack() {
      uni.navigateBack({ delta: 1 });
    },
    // 监听NFC标签
    NFClistener() {
      this.NFCAdapter.startDiscovery({
        success: () => {
          this.title = "开启NFC适配器成功!";
        },
        fail: (error) => {
          console.log("开启NFC适配器失败！", error);

          uni.showToast({
            title: "开启NFC适配器失败",
            icon: "error",
            mask: true,
          });
          this.title = "开启NFC适配器失败!";
          this.infoState = 0;
        },
      });
    },

    // 验证 监听回调
    validateDiscoverHandler(callback) {
      console.log("==================== START ====================");
      console.log("onDiscovered callback=>", callback);
      if (callback.techs.length != 0) {
        this.title = "识别成功！";
        this.infoState = 1;
      } else {
        this.title = "无效设备!";
        this.infoState = 0;
      }

      if (callback.messages) {
        let cordsArray = callback.messages[0].records;
        cordsArray.forEach((item) => {
          const read = {
            payload: formatNullCharacter(
              byteToString(new Uint8Array(item.payload))
            ),
            id: byteToString(new Uint8Array(item.id)),
            type: byteToString(new Uint8Array(item.type)),
          };
          const validateItem = this.validateItem;
          let title = "";
          let icon = "";
          let verificationState = "";
          let infoState = 1;

          if (validateItem.text == this.read.payload) {
            title = "验证成功~";
            icon = "none";
            verificationState = 1;
          } else {
            title = "验证失败！";
            icon = "error";
            verificationState = 2;
            infoState = 0;
          }
          this.title = title;
          this.read = read;
          this.infoState = infoState;
          this.keyList[validateItem.idx - 1].verificationState =
            verificationState;
          console.log("数据验证时的keyList", this.keyList);
          uni.showToast({
            title: title,
            icon: icon,
            mask: true,
          });
          this.handleSyncStorageKey();
        });
      }
      console.log("read", this.read);

      this.NFCAdapter.offDiscovered(this.validateDiscoverHandler);
      console.log("===================== END =====================");
    },

    // 写入 NFC 标签
    onWriteNdefInfo: throttle(function (e) {
      const item = e.currentTarget.dataset.item;
      this.writeItem = item;
      wx.showToast({
        title: "靠近NFC标签",
        icon: "loading",
        duration: 100000,
      });
      // 监听 NFC 标签
      this.NFCAdapter.onDiscovered(this.writeDiscoverHandler);
    }),

    // 监听写入回调
    async writeDiscoverHandler() {
      wx.showToast({
        title: "识别NFC标签",
        icon: "loading",
        duration: 1000000,
      });

      const NFCTab = await this.initTab();

      if (!NFCTab) return;

      const writeItem = this.writeItem;
      let title = "";
      let icon = "none";
      let writeState = 0;
      let infoState = 1;
      let read = {
        type: "",
        payload: "",
      };

      // 执行写入
      NFCTab.writeNdefMessage({
        uris: [writeItem.text],
        success: () => {
          title = "数据写入成功";
          icon = "success";
          writeState = 1;
          read.type = "U";
          read.payload = writeItem.text;
        },
        fail: () => {
          title = "数据写入失败";
          icon = "error";
          writeState = 2;
          infoState = 0;
        },
        complete: (res) => {
          console.log("数据写入: res", res);
          uni.showToast({
            title: title,
            icon: icon,
            mask: true,
          });
          this.title = title;
          this.read = read;
          this.infoState = infoState;
          this.keyList[writeItem.idx - 1].writeState = writeState;
          console.log("数据写入时的keyList", this.keyList);
          this.closeConnect(NFCTab);
          this.handleSyncStorageKey();
        },
      });
    },

    // 链接NFC标签
    initTab() {
      const NFCTab = this.NFCAdapter.getNdef();
      return new Promise((resolve, reject) => {
        NFCTab.connect({
          success: () => {
            this.title = "连接设备成功";
            this.infoState = 1;
            resolve(NFCTab);
          },
          fail: (error) => {
            console.log("error", error);
            wx.showToast({
              title: "连接设备失败",
              icon: "error",
            });
            this.title = "连接设备失败";
            this.infoState = 0;
            this.NFCAdapter.offDiscovered(this.writeDiscoverHandler);
            reject();
          },
        });
      });
    },

    // 读写完毕，断开连接
    closeConnect(NFCTab) {
      NFCTab.close({
        complete: (res) => {
          console.log("清除标签连接：res", res);
          this.NFCAdapter.offDiscovered(this.writeDiscoverHandler);
        },
      });
    },

    // 验证
    onValidate: throttle(function (e) {
      const item = e.currentTarget.dataset.item;
      this.validateItem = item;

      wx.showToast({
        title: "靠近NFC标签",
        icon: "loading",
        duration: 1000000,
      });
      // 监听 NFC 标签
      this.NFCAdapter.onDiscovered(this.validateDiscoverHandler);
    }),

    // 同步数据
    handleSyncStorageKey() {
      wx.setStorageSync(this.key, this.keyList);
    },
    closeNFC() {
      if (this.NFCAdapter) {
        this.NFCAdapter.offDiscovered(this.writeDiscoverHandler);
        this.NFCAdapter.offDiscovered(this.validateDiscoverHandler);
        this.NFCAdapter.stopDiscovery();
        this.NFCAdapter = null;
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.page {
  position: relative;
  height: 100vh;
}

.info-wrap {
  width: 100%;
  padding: 20rpx;
  box-sizing: border-box;
  background-color: #fff;
}

.info-wrap .info-box {
  min-height: 280rpx;
  font-size: 28rpx;
  font-weight: 600;
  text-align: center;
  border-radius: 15rpx;
  overflow: hidden;
  color: #fff;
  background-color: #22c068;
  padding: 16px;
}

.info-wrap .info-box-error {
  background-color: #e45b57;
}

.info-box .title {
  // line-height: 100rpx;
}

.info-box .text {
  padding-left: 20rpx;
  text-align: left;
  line-height: 50rpx;
}

.key-list {
  height: calc(100vh - 340rpx - constant(safe-area-inset-bottom));
  height: calc(100vh - 340rpx - env(safe-area-inset-bottom));
  padding: 20rpx;
  box-sizing: border-box;
  background-color: #f2f2f2;
}

.key-item {
  margin-bottom: 30rpx;
  border-radius: 10rpx;
  background-color: #fff;
  overflow: hidden;
}

.top-block {
  display: flex;
  border-bottom: 1px solid #f2f2f2;
}

.top-block .idx {
  display: block;
  padding-left: 20rpx;
  padding-top: 30rpx;
}

.top-block .content {
  padding: 20rpx;
}

.bottom-block {
  display: flex;
  align-items: center;
  justify-content: center;
}

.bottom-block .btn {
  width: 300rpx;
  border-radius: 10rpx;
  text-align: center;
  margin: 20rpx;
  font-size: 28rpx;
  font-weight: bolder;
}

.end-item {
  text-align: center;
  line-height: 100rpx;
  color: #999;
  font-weight: bolder;
}
</style>
